#include <Arduino.h>
#include <Arduino.h>
#include <TFT_eSPI.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <cstring>  // 包含cstring库
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include "As.h"
#include "weacher_pic.h"
#include "Weather.h"
#include "Connect.h"
#include "DHT11.h"
#include "Date_S.h"
#include "font_14.h"
#include "font_16.h"
#include "font_38.h"
#include "font_30.h"
#include "font_26.h"

#define           WEATHER_UPDATE_TIME         1200000   /* 天气更新频率ms， 设置的是20分钟更新一次 */ 
#define           DHT_UPDATE_TIME             15000   /* 天气更新频率ms， 设置的是15s更新一次 */ 
#define           DHT_PIN                     D2  /* 温湿度引脚 */ 

const char WEATHER_URL[] = "http://cloud.tq.360.cn/weather/city/101180109"; // 天气url
const char DATE_URL[] = "http://quan.suning.com/getSysTime.do"; // 获取系统时间
const char *WIFI_SSID = "和动"; 
const char *WIFI_PASSWORD = "20230328HD";
// const char *WIFI_SSID = "CMCC-G65F"; 
// const char *WIFI_PASSWORD = "zz12345678";
TFT_eSPI tft = TFT_eSPI(128, 160);  // 在创建对象的时候设置屏幕尺寸
Date_S date_s; // 系统时间
Weather weather; // 天气对象
Date_S last_date_s; // 上一次更新的系统时间
Weather last_weather; // 上一次更新的天气对象
uint8_t DHT11_Data[5]; // 缓存的DHT11数据
DHT_Data DHT_data; // 读取到的DHT11数据
DHT_Data last_DHT_data; // 上一次读取到的DHT11数据
// int scrollTextX = 0; // 滚动文字 X 的位置
// unsigned long scrollTextXLastUpdateTime;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("...kaishi");
  tft.init();
  tft.setRotation(0);
  tft.setSwapBytes(true);
  // tft.setTextFont(1); // 设置线宽为2
  tft.fillScreen(0x0000);
  // 绘制连接状态
  // drawConnect();

  wifi_connect();
  while(send_http_weather(&weather) == "error");
  
  while(send_http_date(&date_s) == "error");
 
   DHT11_Receive_Data();
   Serial.println("数据获取成功！");
   Serial.println(weather.temperature);
   Serial.println(date_s.year);
  
   drawCanvas(&weather, &date_s);

}

void loop() {
  
  // put your main code here, to run repeatedly:
  // 系统运行时常， 单位ms
  unsigned long runtime = millis();
  if (date_s.lastUpdateTime > 0 && runtime - date_s.lastUpdateTime >= 1000) {
    // Serial.print("时间：");
    // Serial.print(runtime - date_s.lastUpdateTime);
    //   Serial.print("--");
    //  Serial.println((double)(runtime - date_s.lastUpdateTime) );
    //   Serial.print("--");
    //   Serial.println((double)(runtime - date_s.lastUpdateTime) / (double)1000 );
    date_s.timeStamp += ((double)(runtime - date_s.lastUpdateTime) / (double)1000);
    parse_timestamp_to_date(&date_s, (time_t)date_s.timeStamp);
    drawTime(&date_s);
    // Serial.print("时间计算结果：");
    // Serial.printf("%.4f\n",  date_s.timeStamp);
    
  }

  // 更新天气
  if (weather.lastUpdateTime > 0 && runtime - weather.lastUpdateTime >= WEATHER_UPDATE_TIME) {
    send_http_weather(&weather);
      // 绘制天气
    drawWeather();
  }
  
  // 更新DHT11
  if (DHT_data.lastUpdateTime > 0 && runtime - DHT_data.lastUpdateTime >= DHT_UPDATE_TIME) {
     DHT11_Receive_Data();
     // 绘制温度
      drawBar(1);
      // 绘制湿度
      drawBar(2);
  }

  // if (runtime - scrollTextXLastUpdateTime > 20) {
  //   drawScrollText();
  // }
 
}



// 发送http请求
String send_http_request(const char *URL) {

  HTTPClient httpClient;              // 初始化http客户端
  WiFiClient wifiClient;              // 建立WiFiClient对象
  httpClient.begin(wifiClient, URL);  // 配置发送的请求
  int httpCode = httpClient.GET();    // 通过GET发送请求
  if (httpCode > 0) {
    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    if (httpCode == HTTP_CODE_OK) {
      String payload = httpClient.getString();  //获取响应体
      Serial.println(payload);
      return payload;
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", httpClient.errorToString(httpCode).c_str());
      return "error";
    }
  } else {
    Serial.printf("[HTTP] Unable to connect\n");
    return "error";
  }

  httpClient.end();
}

void wifi_connect() {
 
  WiFi.mode(WIFI_STA);         // 设置WiFi工作模式
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);  // 通过wifi名称和密码链接wifi
  Serial.println("wifi 连接中...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);  // 延时1秒
    Serial.println("等待连接...");
  }
  Serial.println("wifi连接成功！");
  Serial.println(WiFi.localIP());
}

// 发送天气请求
String send_http_weather (Weather *weather) {
  String data = send_http_request(WEATHER_URL);
  if (data == "error") {
    Serial.print("send_http_request() failed: ");
    return "error";
  }

  //1、JsonDocument doc  对象
  JsonDocument doc;
  // 解析json
  DeserializationError error = deserializeJson(doc, data);

  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return "error";
  }
  parse_to_Weather(weather, doc);
  return "ok";
}

void parse_to_Weather(Weather *w, JsonDocument doc) {
  // 缓存上一次的信息
  memcpy(last_weather.info, w->info, sizeof(w->info) / sizeof(w->info[0]));
  memcpy(last_weather.temperature, w->temperature, sizeof(w->temperature) / sizeof(w->temperature[0]));
  memcpy(last_weather.pressure, w->pressure, sizeof(w->pressure) / sizeof(w->pressure[0]));
  memcpy(last_weather.humidity, w->humidity, sizeof(w->humidity) / sizeof(w->humidity[0]));
  memcpy(last_weather.windDirection, w->windDirection, sizeof(w->windDirection) / sizeof(w->windDirection[0]));
  memcpy(last_weather.windSpeed, w->windSpeed, sizeof(w->windSpeed) / sizeof(w->windSpeed[0]));
  memcpy(last_weather.windScale, w->windScale, sizeof(w->windScale) / sizeof(w->windScale[0]));
  memcpy(last_weather.lastUpdate, w->lastUpdate, sizeof(w->lastUpdate) / sizeof(w->lastUpdate[0]));
  last_weather.picIndex = w->picIndex;
  last_weather.lastUpdateTime = w->lastUpdateTime;
  Weather_Location last_wl;
  memcpy(last_wl.provinceId, w->location.provinceId, sizeof( w->location.provinceId) / sizeof( w->location.provinceId[0]));
  memcpy(last_wl.provinceName, w->location.provinceName, sizeof( w->location.provinceName) / sizeof( w->location.provinceName[0]));
  memcpy(last_wl.cityId, w->location.cityId, sizeof( w->location.cityId) / sizeof( w->location.cityId[0]));
  memcpy(last_wl.cityName, w->location.cityName, sizeof( w->location.cityName) / sizeof( w->location.cityName[0]));
  memcpy(last_wl.countyId, w->location.countyId, sizeof( w->location.countyId) / sizeof( w->location.countyId[0]));
  memcpy(last_wl.countyName, w->location.countyName, sizeof( w->location.countyName) / sizeof( w->location.countyName[0]));
  last_weather.location = w->location;
  
  const char *temperature = doc["realtime"]["weather"]["temperature"];
  const char *humidity = doc["realtime"]["weather"]["humidity"];
  const char *info = doc["realtime"]["weather"]["info"];
  const char *windSpeed = doc["realtime"]["wind"]["windspeed"];
  const char *windDirection = doc["realtime"]["wind"]["direct"];
  const char *windScale = doc["realtime"]["wind"]["power"];
  const char *pressure = doc["realtime"]["pressure"];
  const char *lastUpdate = doc["realtime"]["dataUptime"];

  const char *provinceName = doc["area"][0][0];
  const char *provinceId = doc["area"][0][1];

  const char *cityName = doc["area"][1][0];
  const char *cityId = doc["area"][1][1];

  const char *countyName = doc["area"][2][0];
  const char *countyId = doc["area"][2][1];

  // 解析天气，并显示对应的图片
  if(strstr(info, "雪") != NULL) {
    // 雪
    w->picIndex = 5;
  } else if (strstr(info, "雨") != NULL) {
    // 雨
    w->picIndex = 7;
  } else if (strstr(info, "雷") != NULL) {
    // 雷
    w->picIndex = 1;
  } else if (strstr(info, "云") != NULL) {
    // 云
    w->picIndex = 8;
  } else if (strstr(info, "雹") != NULL) {
    // 雹
    w->picIndex = 0;
  } else if (strstr(info, "雾") != NULL) {
    // 雾
    w->picIndex = 4;
  } else if (strstr(info, "沙") != NULL) {
    // 沙
    w->picIndex = 3;
  } else if (strstr(info, "阴") != NULL) {
    // 阴
    w->picIndex = 6;
  } else if (strstr(info, "晴") != NULL) {
    // 晴
    w->picIndex = 2;
  }

  strcpy(w->temperature, temperature);
  strcpy(w->humidity, humidity);
  strcpy(w->info, info);
  strcpy(w->windSpeed, windSpeed);
  strcpy(w->windDirection, windDirection);
  strcpy(w->windScale, windScale);
  strcpy(w->pressure, pressure);
  strcpy(w->lastUpdate, lastUpdate);
  w->lastUpdateTime = millis();
  Weather_Location wl;
  strcpy(wl.provinceName, provinceName);
  strcpy(wl.provinceId, provinceId);
  strcpy(wl.cityName, cityName);
  strcpy(wl.cityId, cityId);
  strcpy(wl.countyName, countyName);
  strcpy(wl.countyId, countyId);
  w->location = wl;
}

// 发送获取时间请求
String send_http_date (Date_S *date_s) {
   String data = send_http_request(DATE_URL);
  if (data == "error") {
    Serial.print("send_http_date_request() failed: ");
    return "error";
  }

  //1、JsonDocument doc  对象
  JsonDocument doc;
  // 解析json
  DeserializationError error = deserializeJson(doc, data);

  if (error) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return "error";
  }
  const char *sysTime2 = doc["sysTime2"];
  Serial.println(sysTime2);
  String parseRes = parse_to_date(date_s, sysTime2);
  return parseRes;
}

/**
* 解析日期：
* l: 2024-09-14 11:57:56
*/
String parse_to_date (Date_S *date_s, const char *l) {
  struct tm time_info;
// 解析时间字符串
  if (strptime(l, "%Y-%m-%d %H:%M:%S", &time_info) == NULL) {
       Serial.println("无法解析时间字符串");
      return "error";
  }
  time_t timeStamp = mktime(&time_info);
  return parse_timestamp_to_date(date_s, timeStamp);
}


/**
* 解析时间戳日期：
* timestamp: 1726391115 单位是秒
*/
String parse_timestamp_to_date (Date_S *date_s, const time_t timestamp) {
  //  =====先缓存上一次的内容
  last_date_s.year = date_s->year;
  last_date_s.month = date_s->month;
  last_date_s.day = date_s->day;
  last_date_s.hour = date_s->hour;
  last_date_s.minute = date_s->minute;
  last_date_s.second = date_s->second;
  last_date_s.weekday = date_s->weekday;
  last_date_s.timeStamp = date_s->timeStamp;
  int j = 0;
  for (j = 0; j < sizeof(date_s->timeStr) / sizeof(date_s->timeStr[0]); j++) {
    last_date_s.timeStr[j] = date_s->timeStr[j];
  }
 
  // 
  struct tm time_info;
  localtime_r(&timestamp, &time_info);
  date_s->year = time_info.tm_year + 1900;
  date_s->month = time_info.tm_mon + 1;
  date_s->day = time_info.tm_mday;
  date_s->hour = time_info.tm_hour;
  date_s->minute = time_info.tm_min;
  date_s->second = time_info.tm_sec;
  date_s->weekday = time_info.tm_wday;
  time_t timeStamp = mktime(&time_info);
  // 只有第一次从万罗上获取时间才会缓存
  if (date_s->timeStamp == double(0)) {
    date_s->timeStamp = (double)timeStamp;
  }
  

  // 记录更新时间
  date_s->lastUpdateTime = millis();

  switch (time_info.tm_wday) {
    case 0:
      strcpy(date_s-> weekdayStr, "周日");
      break;
    case 1:
      strcpy(date_s-> weekdayStr, "周一");
      break;
    case 2:
      strcpy(date_s-> weekdayStr, "周二");
      break;
    case 3:
      strcpy(date_s-> weekdayStr, "周三");
      break;
    case 4:
      strcpy(date_s-> weekdayStr, "周四");
      break;
    case 5:
      strcpy(date_s-> weekdayStr, "周五");
      break;
    case 6:
      strcpy(date_s-> weekdayStr, "周六");
      break;
  }

  char l[80]; // 足够大以存储格式化后的时间字符串
  strftime(l, sizeof(l), "%Y-%m-%d %H:%M:%S", &time_info); // 格式化时间

  int i = 0, idx = 0;
  while(l[i] != '\0') {
    if (l[i] >= '0' && l[i] <= '9') {
      date_s->timeStr[idx++] = l[i];
    }
    i++;
  }

  
  return "ok";
}

void drawCanvas (Weather *weather, Date_S *date_s) {
  // 绘制天气
  drawWeather();

  // 绘制太空人
  // drawASImage ();

  // 绘制时间
  drawTime(date_s);
  
  // 一绘制温度、湿度图标
  tft.pushImage(0, 112, 24, 24, wendu);
  tft.pushImage(0, 136, 24, 24, shidu);


}

// 绘制天气图标
void drawWeatherImage (Weather *weather) {
  tft.pushImage(88, 0, 40, 40, weathers[weather->picIndex]);
}

// 绘制太空人图标
void drawASImage () {
  tft.pushImage(128 - 50, 160 - 50, 50, 50, Astronaut[0]);
}

/**
* 绘制文字
* TextColor 字体颜色
* TextSize 字体大小
* CursorX 横坐标
* CursorY 纵坐标
* Text 文字
*/
void printText(short TextColor, char TextSize, char CursorX, char CursorY, char *Text) {
  tft.setTextColor(TextColor);      // 设置文字颜色为白色
  tft.setTextSize(TextSize);        // 设置文字大小
  tft.setCursor(CursorX, CursorY);  // 设置文字开始的位置（x, y）
  tft.println(Text);                // 在屏幕上打印文字
}

/**
* text 文字
* textColor 颜色
* textDatum 对其方式
*
*/
void drawString (char *text, short textColor, char textDatum, char x, char y, const uint8_t *font ) {
  tft.loadFont(font);
  tft.setTextDatum(textDatum);
  tft.setTextColor(textColor, TFT_BLACK);
  tft.drawString(text, x, y);
  tft.unloadFont();
}

// 画温湿度条以及数值
// type 1 温度  2湿度   value为显示的数值
void drawBar (char type) {
  // 定义 温度 范围 -15 - 45℃；填充颜色 0XFC0E, 绘制最左边中心点位置 x: 32, y: 136 - 24 + 12; 条长度 28
  // 定义 湿度 范围 0 - 100%；填充颜色 0x8E7E, 绘制最左边中心点位置 x: 32, y: 136 + 12; 条长度 28
  char value, realValue;
  if (type == 1) {
    value = atoi(weather.temperature);
    realValue = (char)round(DHT_data.temperature);
  } else {
    value = atoi(weather.humidity);
    realValue = (char)DHT_data.humidity;
  }
  short min_range, max_range, width, fillWidth;
  short color;
  char r = 3, ir = 2; // r外原型半径， ir内圆半径
  short x, y;
  char unit[5];
  if (type == 1) {
    width = 26;
    min_range = -15;
    max_range = 45;
    color = 0XFC0E;
    x = 32;
    y = 124;
    fillWidth = (short)(((float)(value - min_range)) / (max_range - min_range) * width);
    strcpy(unit, "℃");
    // Serial.println("温度：");
    // Serial.println(fillWidth);
  } else {
     width = 26;
     min_range = 0;
     max_range = 100;
     color = 0x8E7E;
     x = 32;
     y = 148;
     fillWidth = (char)(((float)(value - min_range)) / (max_range - min_range) * width);
     
     strcpy(unit, "%");
  }
  char endX = x + width;
  tft.drawArc(x, y, r, ir, 0, 180, TFT_WHITE, TFT_BLACK);
  tft.drawArc(endX, y, r, ir, 180, 360, TFT_WHITE, TFT_BLACK);
  tft.drawLine(x, y - r, endX, y - r, TFT_WHITE);
  tft.drawLine(x, y + r, endX, y + r, TFT_WHITE);
  // 绘制填充线
  
  // tft.drawWideLine(x, y, x + fillWidth, y, ir * 2, color);
  // tft.drawWideLine(x + fillWidth, y, x + width, y, ir * 2, TFT_BLACK);
  tft.fillRect(x-1, y-ir, fillWidth, ir * 2 + 1, color);
  tft.fillRect(x-1 + fillWidth, y-ir, width - fillWidth, ir * 2 + 1, TFT_BLACK);
  // 绘制从网络上获取的温湿度信息
  char oldBuf[20];
  char buf[20];
  if (type == 1) {
    sprintf(oldBuf, "%d%s", atoi(last_weather.temperature), unit);
  } else {
    sprintf(oldBuf, "%d%s", atoi(last_weather.humidity), unit);
  }
  sprintf(buf, "%d%s", value, unit);
  // Serial.println("温度-----：");
  // Serial.println(buf);
  drawString(oldBuf, TFT_BLACK, MC_DATUM, endX + 18, y, font_14);
  drawString(buf, TFT_WHITE, MC_DATUM, endX + 18, y, font_14);

  // 绘制从DHT11上获取的温湿度信息
  char oldRealBuf[20];
  char realbuf[20];
  if (type == 1) {
    sprintf(oldRealBuf, "%d%s", (char)round(last_DHT_data.temperature), unit);
  } else {
    sprintf(oldRealBuf, "%d%s", (char)last_DHT_data.humidity, unit);
  }
  sprintf(realbuf, "%d%s", realValue, unit);
  // Serial.println("DHT11温度-----：");
  // Serial.println(realbuf);
  drawString(oldRealBuf, TFT_BLACK, MC_DATUM, endX + 50, y, font_14);
  drawString(realbuf, TFT_WHITE, MC_DATUM, endX + 50, y, font_14);
}

// 绘制天气
void drawWeather () {
  if (strcmp(weather.location.cityName, last_weather.location.cityName) != 0) {
     // 绘制城市
    drawString(last_weather.location.cityName, TFT_BLACK, CC_DATUM, 128 / 5, 10, font_16);
    drawString(weather.location.cityName, TFT_WHITE, CC_DATUM, 128 / 5, 10, font_16);
  }

  if (strcmp(weather.info, last_weather.info) != 0 || strcmp(weather.windDirection, last_weather.windDirection) != 0) {
    char oldBuf[50];
    sprintf(oldBuf, "%s %s", last_weather.info, last_weather.windDirection);
    char buf[50];
    sprintf(buf, "%s %s", weather.info, weather.windDirection);

    // 绘制天气文字
    drawString(oldBuf, TFT_BLACK, CC_DATUM, 128 / 5 * 1.5, 30, font_16);
    drawString(buf, TFT_WHITE, CC_DATUM, 128 / 5 * 1.5, 30, font_16);
  }
 
  // 绘制天气图标
  drawWeatherImage(&weather);

  // 绘制温度
  drawBar(1);
  // 绘制湿度
  drawBar(2);
}

void drawTime (Date_S *date_s) {

  // tft.fillRect(0, 45, 128, 80, TFT_BLACK);
  
   // 绘制小时
  if (last_date_s.hour != date_s->hour) {
    char oldHour1[] = {last_date_s.timeStr[8], '\0'};
    char oldHour2[] = {last_date_s.timeStr[9], '\0'};
    char hour1[] = {date_s->timeStr[8], '\0'};
    char hour2[] = {date_s->timeStr[9], '\0'};
    drawString(oldHour1, TFT_BLACK, TL_DATUM, 0, 45, font_38);
    drawString(oldHour2, TFT_BLACK, TL_DATUM, 19, 45, font_38);
    drawString(hour1, 0x8E7E, TL_DATUM, 0, 45, font_38);
    drawString(hour2, 0x8E7E, TL_DATUM, 19, 45, font_38);
  }
  char dot[] = "·";
  // 绘制·
  drawString(dot, TFT_WHITE, TL_DATUM, 36, 45, font_26);
  drawString(dot, TFT_WHITE, BL_DATUM, 36, 90, font_26);


  if (last_date_s.minute != date_s->minute) {
    char oldMinute1[] = {last_date_s.timeStr[10], '\0'};
    char oldMinute2[] = {last_date_s.timeStr[11], '\0'};
    char minute1[] = {date_s->timeStr[10], '\0'};
    char minute2[] = {date_s->timeStr[11], '\0'};
    // 绘制分钟
    drawString(oldMinute1, TFT_BLACK, TL_DATUM, 57, 45, font_38);
    drawString(oldMinute2, TFT_BLACK, TL_DATUM, 76, 45, font_38);
    drawString(minute1, 0xFDE0, TL_DATUM, 57, 45, font_38);
    drawString(minute2, 0xFDE0, TL_DATUM, 76, 45, font_38);
  }
  
  if (last_date_s.second != date_s->second) {
    char oldSecond[] = {last_date_s.timeStr[12], last_date_s.timeStr[13],'\0'};
    char second[] = {date_s->timeStr[12], date_s->timeStr[13],'\0'};

    // 绘制秒针
    drawString(oldSecond, TFT_BLACK, BR_DATUM, 128, 86, font_26);
    drawString(second, TFT_WHITE, BR_DATUM, 128, 86, font_26);
  }
  
   if (last_date_s.month != date_s->month || last_date_s.day != date_s->day || last_date_s.weekday != date_s->weekday) {
     // 绘制日历
      char oldDrawText[80];
      sprintf(oldDrawText, "今日%d月%d日 %s", last_date_s.month, last_date_s.day, last_date_s.weekdayStr);
      char drawText[80];
      sprintf(drawText, "今日 %d月%d日 %s", date_s->month, date_s->day, date_s->weekdayStr);
      drawString(oldDrawText, TFT_BLACK, TL_DATUM, 0, 93, font_16);
      drawString(drawText, TFT_WHITE, TL_DATUM, 0, 93, font_16);
   }
 
}
// void drawScrollText () {
//     scrollTextX--;
//     // 绘制日历
//     char oldDrawText[80];
//     sprintf(oldDrawText, "今日%d月%d日 %s", last_date_s.month, last_date_s.day, last_date_s.weekdayStr);
//     char drawText[80];
//     sprintf(drawText, "今日 %d月%d日 %s", date_s.month, date_s.day, date_s.weekdayStr);
//     drawString(oldDrawText, TFT_BLACK, TL_DATUM, scrollTextX, 93, font_16);
//     drawString(drawText, TFT_WHITE, TL_DATUM, scrollTextX, 93, font_16);
//     scrollTextXLastUpdateTime = millis();
// }


// 绘制连接状态
void drawConnect () {
  tft.pushImage(14, 50, 100, 20, ConnectWifi[0]);
}


int DHT11_begin () {
  pinMode(DHT_PIN, OUTPUT); // VDD设置输出模式
  // 设置低电平，时间为18-30ms
  digitalWrite(DHT_PIN, LOW);
  delay(20);
  pinMode(DHT_PIN, INPUT_PULLUP); // DATA设置上啦输入
  delayMicroseconds(13);
  // 等待从机 拉低 拉电平结束
	if (digitalRead(DHT_PIN) == LOW) {
		while (digitalRead(DHT_PIN) == LOW);
		while (digitalRead(DHT_PIN) == HIGH);
		return 1;
	}
	return 0;
  
}


int DHT11_Read_Bit () {
  // 跳过低电平的时间
	while (digitalRead(DHT_PIN) == LOW);
	// 此时为高电平刚开始，
	// 0 高电平时间 23-27us；  1高电平时间68-74us
	// 判断30us后，如果为低电平则为0；高电平则为1
	delayMicroseconds(30);
	if (digitalRead(DHT_PIN) == LOW) {
		return 0;
	} else {
		// 注意，此时我们应等待高电平结束
		while(digitalRead(DHT_PIN) == HIGH);
		return 1;
	}
}


// 读取一个字节数据
int DHT11_Read_Byte () {
	int i = 8;
	int data = 0x00;
	for (i = 0; i < 8; i++) {
		data <<= 1;
		data |= DHT11_Read_Bit();
	}
	return data;
}


// 接受数据
int DHT11_Receive_Data () {
	if (DHT11_begin()) {
		DHT11_Data[0] = DHT11_Read_Byte();
		DHT11_Data[1] = DHT11_Read_Byte();
		DHT11_Data[2] = DHT11_Read_Byte();
		DHT11_Data[3] = DHT11_Read_Byte();
		DHT11_Data[4] = DHT11_Read_Byte();
		// 从机释放总线
		delayMicroseconds(60);
		if ( DHT11_Data[4] == (DHT11_Data[0] + DHT11_Data[1] + DHT11_Data[2] + DHT11_Data[3])) {
      // 先缓存上一次的数据
      last_DHT_data.temperature = DHT_data.temperature;
      last_DHT_data.humidity = DHT_data.humidity;
      last_DHT_data.lastUpdateTime = DHT_data.lastUpdateTime;
      
			// 结构体存储数据
			char temperature[50];
			sprintf(temperature, "%d.%d", DHT11_Data[2], DHT11_Data[3]);
			DHT_data.temperature = atof(temperature);
	
			char humidity[50];
			sprintf(humidity, "%d.%d", DHT11_Data[0], DHT11_Data[1]);
			DHT_data.humidity = atof(humidity);

      DHT_data.lastUpdateTime = millis();
			
			// Serial.print("读取到的温度-----：");
      // Serial.println(DHT_data.temperature);
      // Serial.print("读取到的湿度----：");
      // Serial.println(DHT_data.humidity);
			return 1;
		} else {
			return 0;
		}
	} else {
		return 0;
	}
}


